package util

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"sigs.k8s.io/kustomize/kyaml/yaml"
)

type HttpResponse struct {
	Code    uint        `json:"code"`
	Message string      `json:"message"`
	Data    interface{} `json:"data"`
}

const (
	ContentJson     = "application/json"
	ContentFormData = "multipart/form-data"
)

func getToken() string {
	envFile, _ := ioutil.ReadFile(os.Getenv("GLUE_CONFIG"))
	envMap := make(map[string]string)

	err := yaml.Unmarshal(envFile, envMap)
	if err != nil {
		panic(err)
	}

	return envMap["token"]
}

// Deprecated
func HttpRequestJson(method string, url string, body []byte) ([]byte, error) {
	req, err := http.NewRequest(method, url, bytes.NewReader(body))
	if err != nil {
		return nil, err
	}

	req.Header.Set("Content-Type", ContentJson)
	return httpRequest(req)
}

// Deprecated
func HttpRequestForm(method string, url string, body []byte) ([]byte, error) {
	req, err := http.NewRequest(method, url, bytes.NewReader(body))
	if err != nil {
		return nil, err
	}

	req.Header.Set("Content-Type", ContentFormData)
	return httpRequest(req)
}

func HttpRequest(method string, url string, body []byte, contentType ...string) ([]byte, error) {
	req, err := http.NewRequest(method, url, bytes.NewReader(body))
	if err != nil {
		return nil, err
	}

	if len(contentType) > 1 {
		return nil, errors.New(fmt.Sprintf("Illegal param contentType nums: expect 1, got %d", len(contentType)))
	}
	if len(contentType) == 1 {
		req.Header.Set("Content-Type", contentType[0])
	} else {
		req.Header.Set("Content-Type", ContentJson)
	}
	return httpRequest(req)
}

func httpRequest(req *http.Request) ([]byte, error) {

	req.Header.Add("token", getToken())

	//fmt.Println(req.Header)

	resp, _ := (&http.Client{}).Do(req)
	responseBody, _ := ioutil.ReadAll(resp.Body)
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return nil, errors.New(fmt.Sprintf("http request error %d", resp.StatusCode))
	}

	var httpResponse HttpResponse
	err := json.Unmarshal(responseBody, &httpResponse)
	if err != nil {
		return nil, err
	} else if httpResponse.Code != 200 {
		return nil, errors.New(fmt.Sprintf("Error %d: %s", httpResponse.Code, httpResponse.Message))
	}

	return responseBody, nil
}
